package text.ui;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.URL;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import org.flexdock.docking.DockingManager;
import org.flexdock.view.View;
import org.flexdock.view.Viewport;

public class GUI extends JPanel {

	// Possible Look & Feels
	private static final String mac	=
			"com.sun.java.swing.plaf.mac.MacLookAndFeel";
	private static final String metal =
			"javax.swing.plaf.metal.MetalLookAndFeel";
	private static final String motif =
			"com.sun.java.swing.plaf.motif.MotifLookAndFeel";
	private static final String windows	=
			"com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
	private static final String gtk	=
			"com.sun.java.swing.plaf.gtk.GTKLookAndFeel";

	// The current Look & Feel
	private static String currentLookAndFeel;

	// The preferred size of the demo
	private static final int PREFERRED_WIDTH = 720;
	private static final int PREFERRED_HEIGHT = 640;
//	private static final int PREFERRED_WIDTH = 1024;
//	private static final int PREFERRED_HEIGHT = 720;
	
	// Resource bundle for internationalized and accessible text
	private ResourceBundle bundle;

	//Center Panel
	private JPanel centerPanel;

	// About Box
	private JDialog aboutBox;

	// Tip Bar
	private JTextField tipField;

	// Tool Bar
	private JButton buttonNew;
	private JButton buttonOpen;
	private JButton buttonSave;
	private JButton buttonSaveAs;
	private JButton buttonCut;
	private JButton buttonCopy;
	private JButton buttonPaste;
	private JButton buttonTrain;
	private JButton buttonTranslate;
	private JButton buttonHelp;
	private JToggleButton buttonTrainingMode;
	private JToggleButton buttonTranslationMode;
	private JToggleButton buttonLexicon;
	private JToggleButton buttonChunks;
	private JToggleButton buttonTemplates;
	private JToggleButton buttonUnused;
	private JToggleButton buttonStatus;
	private JButton buttonTrace;
	private ToggleButtonToolBar toolbar;
	private ButtonGroup toolbarModeGroup;

	// Menus
	private JMenuBar menuBar;
	private JMenu fileMenu;
	private JMenu editMenu;
	private JMenu searchMenu;
	private JMenu viewMenu;
	private JMenu modeMenu;
	private JMenu commandsMenu;
	private JMenu lafMenu;
	private JMenu helpMenu;
	private ButtonGroup modeMenuGroup;
	private ButtonGroup lafMenuGroup;

	//Menu Items
	private JMenuItem newMI;
	private JMenuItem openMI;
	private JMenuItem saveMI;
	private JMenuItem saveAsMI;
	private JMenuItem cutMI;
	private JMenuItem copyMI;
	private JMenuItem pasteMI;
	private JMenuItem lexiconViewMI;
	private JMenuItem templatesViewMI;
	private JMenuItem chunksViewMI;
	private JMenuItem unusedViewMI;
	private JMenuItem statusViewMI;
	private JMenuItem trainingModeMI;
	private JMenuItem translationModeMI;
	private JMenuItem trainMI;
	private JMenuItem translateMI;
	private JMenuItem traceMI;
	
	// Used only if gui is an application 
	private static JFrame frame;
	private JWindow splashScreen;

	private JLabel splashLabel;

	// contentPane cache, saved from the applet or application frame
	Container contentPane;

	// number of guis - for multiscreen
	// keep track of the number of GUIs created - we only want to exit
	// the program when the last one has been closed.
	private static int numSSs = 0;
	private static Vector guis = new Vector();

	//Actions
	private ModeAction trainingModeActionObj;
	private ModeAction translationModeActionObj;
	private LexiconAction lexiconActionObj;
	private ChunksAction chunksActionObj;
	private TemplatesAction templatesActionObj;
	private UnusedAction unusedActionObj;
	private StatusAction statusActionObj;
	private HelpAction helpActionObj;
	
	//Viewers
	private TrainingModeViewer trainingModeViewerObj;
	private TranslationModeViewer translationModeViewerObj;
	private View modePage;
	private LexiconViewer lexiconViewerObj;
	private View viewLexicon;
	private ChunksViewer chunksViewerObj;
	private View viewChunks;
	private TemplatesViewer templatesViewerObj;
	private View viewTemplates;
	private UnusedSentencesViewer unusedViewerObj;
	private View viewUnused;
	private static StatusViewer statusViewerObj;
	private View viewStatus;
	private HelpViewer helpViewerObj;
	
	//Mode
	private final String MODE_TRAINING = "Training";
	private final String MODE_TRANSLATION = "Translation";
	private String mode;
	
    public final static int ONE_SECOND = 1000;
    public final static int TASK_LENGTH = 100;

    private static JProgressBar progressBar;
    private static Timer timer;

    public static boolean isDone = false;

	public void setMIandButtonsEnabled(boolean bEnable) {
		if(trainingModeViewerObj != null)
			trainingModeViewerObj.setEnabled(bEnable);
		if(translationModeViewerObj != null)
			translationModeViewerObj.setEnabled(bEnable);
		if(lexiconViewerObj != null)
			lexiconViewerObj.setEnabled(bEnable);
		if(chunksViewerObj != null)
			chunksViewerObj.setEnabled(bEnable);
		if(templatesViewerObj != null)
			templatesViewerObj.setEnabled(bEnable);
		if(unusedViewerObj != null)
			unusedViewerObj.setEnabled(bEnable);
		
		buttonNew.setEnabled(bEnable);
		buttonOpen.setEnabled(bEnable);
		buttonSave.setEnabled(bEnable);
		buttonSaveAs.setEnabled(bEnable);
		buttonCut.setEnabled(bEnable);
		buttonCopy.setEnabled(bEnable);
		buttonPaste.setEnabled(bEnable);
		
		if(bEnable && getMode() instanceof TrainingModeViewer) {
			buttonTrain.setEnabled(bEnable);
			trainMI.setEnabled(bEnable);
		}else if(bEnable && getMode() instanceof TranslationModeViewer) {
			buttonTranslate.setEnabled(bEnable);
			translateMI.setEnabled(bEnable);
		}else {
			buttonTrain.setEnabled(bEnable);
			trainMI.setEnabled(bEnable);
			buttonTranslate.setEnabled(bEnable);
			translateMI.setEnabled(bEnable);
		}
				
		buttonLexicon.setEnabled(bEnable);
		buttonChunks.setEnabled(bEnable);
		buttonTemplates.setEnabled(bEnable);
		buttonUnused.setEnabled(bEnable);
		buttonStatus.setEnabled(bEnable);
		buttonTrace.setEnabled(bEnable);
		buttonHelp.setEnabled(bEnable);
		buttonTrainingMode.setEnabled(bEnable);
		buttonTranslationMode.setEnabled(bEnable);
		toolbar.setEnabled(bEnable);

		menuBar.setEnabled(bEnable);
		
		newMI.setEnabled(bEnable);
		openMI.setEnabled(bEnable);
		saveMI.setEnabled(bEnable);
		saveAsMI.setEnabled(bEnable);
		cutMI.setEnabled(bEnable);
		copyMI.setEnabled(bEnable);
		pasteMI.setEnabled(bEnable);
		lexiconViewMI.setEnabled(bEnable);
		templatesViewMI.setEnabled(bEnable);
		chunksViewMI.setEnabled(bEnable);
		unusedViewMI.setEnabled(bEnable);
		statusViewMI.setEnabled(bEnable);
		traceMI.setEnabled(bEnable);
		trainingModeMI.setEnabled(bEnable);
		translationModeMI.setEnabled(bEnable);
	}

	/**
	 * GUI Constructor
	 */
	public GUI(GraphicsConfiguration gc) {
		// Create Frame here for app-mode so the splash screen can get the
		// GraphicsConfiguration from it in createSplashScreen()
		frame = createFrame(gc);
	
		// setLayout(new BorderLayout());
		setLayout(new BorderLayout());
	
		// set the preferred size of the demo
		setPreferredSize(new Dimension(PREFERRED_WIDTH,PREFERRED_HEIGHT));
	
		// Create and throw the splash screen up. Since this will
		// physically throw bits on the screen, we need to do this
		// on the GUI thread using invokeLater.
		createSplashScreen();
	
		// do the following on the gui thread
		if(splashScreen != null) {
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					showSplashScreen();
				}
			});
		}

		//vars are init
		currentLookAndFeel = metal;
		toolbarModeGroup = new ButtonGroup();
		modeMenuGroup = new ButtonGroup();
		lafMenuGroup = new ButtonGroup();

		initializeGUI();
	
		// Show the demo and take down the splash screen. Note that
		// we again must do this on the GUI thread using invokeLater.
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				showGUI();
				if(splashScreen != null) {
					hideSplash();
				}
			}
		});
	}


	/**
	 * GUI Main. Called only if we're an application, not an applet.
	 */
	public static void main(String[] args) {
		GUI gui = new GUI(GraphicsEnvironment.
											 getLocalGraphicsEnvironment().
											 getDefaultScreenDevice().
											 getDefaultConfiguration());
	}

	// *******************************************************
	// ****************** Loading Methods ********************
	// *******************************************************
	
	
	
	public void initializeGUI() {
		updateLookAndFeel();

		JPanel top = new JPanel();
		top.setLayout(new BorderLayout());
		add(top, BorderLayout.NORTH);

		//Viewers
		lexiconViewerObj = new LexiconViewer(this);
		chunksViewerObj = new ChunksViewer(this);
		templatesViewerObj = new TemplatesViewer(this);
		unusedViewerObj = new UnusedSentencesViewer(this);
		statusViewerObj = new StatusViewer();
		helpViewerObj = new HelpViewer();
		
		//Menu Bar
		menuBar = createMenus();
		
		frame.setJMenuBar(menuBar);
	
		//Tool Bar
		ToolBarPanel toolbarPanel = new ToolBarPanel();
		toolbarPanel.setLayout(new BorderLayout());
		toolbar = new ToggleButtonToolBar();
		toolbarPanel.add(toolbar, BorderLayout.CENTER);
		top.add(toolbarPanel, BorderLayout.SOUTH);
		toolbarPanel.addContainerListener(toolbarPanel);

		createToolBar();	

		//turn on floating support for docks
		DockingManager.setFloatingEnabled(true);
		centerPanel = createCenterPanel();

//		DockingManager.close(viewLexicon);
		DockingManager.close(viewChunks);
		DockingManager.close(viewTemplates);
		DockingManager.close(viewUnused);

		//Center Panel
		add(centerPanel, BorderLayout.CENTER);

//public static PrintWriter 
		//Status Area
//		out = new PrintWriter(new FileWriter("log.txt"));

		JPanel bottom = new JPanel();
		bottom.setLayout(new BorderLayout());

		//Status Field
		tipField = new JTextField("");
		tipField.setEditable(false);
		bottom.add(tipField, BorderLayout.CENTER);
		
        progressBar = new JProgressBar(0, TASK_LENGTH);
        progressBar.setValue(0);
        progressBar.setStringPainted(true); //get space for the string
        progressBar.setString("");          //but don't paint it
		bottom.add(progressBar, BorderLayout.EAST);
		
		//bottom.add(new JPanel(), BorderLayout.CENTER);
		add(bottom, BorderLayout.SOUTH);
		
		setTip(getString("Status.helpTip"));

        timer = new Timer(ONE_SECOND, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
            	if(isDone) {
            		progressBar.setValue(TASK_LENGTH);
                }else {
	                progressBar.setValue(0);
                }

                if (isDone) {
                    if (progressBar.isIndeterminate()) {
                        progressBar.setIndeterminate(false);
                        progressBar.setString(null); //display % string
                    }
                    Toolkit.getDefaultToolkit().beep();
                    timer.stop();
                    progressBar.setValue(progressBar.getMinimum());
                    progressBar.setString(""); //hide % string
                }
            }
        });
	}

	/**
	 * Create menus
	 */
	public JMenuBar createMenus() {
		JMenuItem mi;
		// ***** create the menubar ****
		JMenuBar menuBar = new JMenuBar();
		menuBar.getAccessibleContext().setAccessibleName(
			getString("MenuBar.accessible_description"));
	
		// ***** create File menu 
		JMenu fileMenu = (JMenu) menuBar.add(new JMenu(getString("FileMenu.label")));
		fileMenu.setMnemonic(getMnemonic("FileMenu.mnemonic"));
		fileMenu.getAccessibleContext().setAccessibleDescription(getString("FileMenu.accessible_description"));
	
		newMI = createMenuItem(fileMenu, "FileMenu.new_label", "FileMenu.new_image", "FileMenu.new_mnemonic",
					 "FileMenu.new_accessible_description", new NewAction(this));
		newMI.setEnabled(false);
		
	 	// register key binding for new file
	 	InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK),
	 		"newAction");
	 	getActionMap().put("newAction", new NewAction(this));

		openMI = createMenuItem(fileMenu, "FileMenu.open_label", "FileMenu.open_image", "FileMenu.open_mnemonic",
					 "FileMenu.open_accessible_description", new OpenAction(this));
		openMI.setEnabled(false);

	 	// register key binding to open
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK),
	 		"openAction");
	 	getActionMap().put("openAction", new OpenAction(this));

		saveMI = createMenuItem(fileMenu, "FileMenu.save_label", "FileMenu.save_image", "FileMenu.save_mnemonic",
					 "FileMenu.save_accessible_description", new SaveAction(this));
		saveMI.setEnabled(false);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK),
	 		"saveAction");
	 	getActionMap().put("saveAction", new SaveAction(this));

		saveAsMI = createMenuItem(fileMenu, "FileMenu.saveas_label", "FileMenu.saveas_image", "FileMenu.saveas_mnemonic",
					 "FileMenu.saveas_accessible_description", new SaveAsAction(this));
		saveAsMI.setEnabled(false);

		fileMenu.addSeparator();
		
		createMenuItem(fileMenu, "FileMenu.exit_label", null, "FileMenu.exit_mnemonic",
				 "FileMenu.exit_accessible_description", new ExitAction(this));
	
		// ***** create edit menu 
		editMenu = (JMenu) menuBar.add(new JMenu(getString("EditMenu.label")));
		editMenu.setMnemonic(getMnemonic("EditMenu.mnemonic"));
		editMenu.getAccessibleContext().setAccessibleDescription(
			getString("EditMenu.accessible_description"));
	
		cutMI = createMenuItem(editMenu, "EditMenu.cut_label", "EditMenu.cut_image", "EditMenu.cut_mnemonic",
					 "EditMenu.cut_accessible_description", new CutAction(this));
		cutMI.setEnabled(false);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK),
	 		"cutAction");
	 	getActionMap().put("cutAction", new CutAction(this));

		copyMI = createMenuItem(editMenu, "EditMenu.copy_label", "EditMenu.copy_image", "EditMenu.copy_mnemonic",
					 "EditMenu.copy_accessible_description", new CopyAction(this));
		copyMI.setEnabled(false);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK),
	 		"copyAction");
	 	getActionMap().put("copyAction", new CopyAction(this));

		pasteMI = createMenuItem(editMenu, "EditMenu.paste_label", "EditMenu.paste_image", "EditMenu.paste_mnemonic",
					 "EditMenu.paste_accessible_description", new PasteAction(this));
		pasteMI.setEnabled(false);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK),
	 		"pasteAction");
	 	getActionMap().put("pasteAction", new PasteAction(this));

		// ***** create view menu
		//viewer actions initializations
		lexiconActionObj = new LexiconAction(this, lexiconViewerObj);
		chunksActionObj = new ChunksAction(this, chunksViewerObj);
		templatesActionObj = new TemplatesAction(this, templatesViewerObj);
		unusedActionObj = new UnusedAction(this, unusedViewerObj);
		statusActionObj = new StatusAction(this, statusViewerObj);
		helpActionObj = new HelpAction(helpViewerObj);
		
		viewMenu = (JMenu) menuBar.add(new JMenu(getString("ViewMenu.label")));
		viewMenu.setMnemonic(getMnemonic("ViewMenu.mnemonic"));
		viewMenu.getAccessibleContext().setAccessibleDescription(
			getString("ViewMenu.accessible_description"));
	
		lexiconViewMI = createMenuItem(viewMenu, "ViewMenu.lexicon_label", "ViewMenu.lexicon_image", "ViewMenu.lexicon_mnemonic",
					 "ViewMenu.lexicon_accessible_description", lexiconActionObj);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.CTRL_DOWN_MASK),
	 		"lexiconAction");
	 	getActionMap().put("lexiconAction", lexiconActionObj);

		chunksViewMI = createMenuItem(viewMenu, "ViewMenu.chunks_label", "ViewMenu.chunks_image", "ViewMenu.chunks_mnemonic",
					 "ViewMenu.chunks_accessible_description", chunksActionObj);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.CTRL_DOWN_MASK),
	 		"chunksAction");
	 	getActionMap().put("chunksAction", chunksActionObj);

		templatesViewMI = createMenuItem(viewMenu, "ViewMenu.templates_label", "ViewMenu.templates_image", "ViewMenu.templates_mnemonic",
					 "ViewMenu.templates_accessible_description", templatesActionObj);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK),
	 		"templatesAction");
	 	getActionMap().put("templatesAction", templatesActionObj);

		unusedViewMI = createMenuItem(viewMenu, "ViewMenu.unused_label", "ViewMenu.unused_image", "ViewMenu.unused_mnemonic",
					 "ViewMenu.unused_accessible_description", unusedActionObj);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_DOWN_MASK),
	 		"unusedAction");
	 	getActionMap().put("unusedAction", unusedActionObj);

		statusViewMI = createMenuItem(viewMenu, "ViewMenu.status_label", "ViewMenu.status_image", "ViewMenu.status_mnemonic",
					 "ViewMenu.status_accessible_description", statusActionObj);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK),
	 		"statusAction");
	 	getActionMap().put("statusAction", statusActionObj);

		fileMenu.addSeparator();
		
		traceMI = createMenuItem(viewMenu, "ViewMenu.trace_label", "ViewMenu.trace_image", "ViewMenu.trace_mnemonic",
					 "ViewMenu.trace_accessible_description", new TraceAction(this));
		traceMI.setEnabled(false);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0),
	 		"traceAction");
	 	getActionMap().put("traceAction", new TraceAction(this));

		// ***** create mode menu 
		//mode actions initializations
		trainingModeActionObj = new ModeAction(this, true);
		translationModeActionObj = new ModeAction(this, false);
		
		modeMenu = (JMenu) menuBar.add(new JMenu(getString("ModeMenu.label")));
		modeMenu.setMnemonic(getMnemonic("ModeMenu.mnemonic"));
		modeMenu.getAccessibleContext().setAccessibleDescription(
			getString("ModeMenu.accessible_description"));
	
		trainingModeMI = createModeMenuItem(modeMenu, "ModeMenu.training_label", "ModeMenu.training_image", "ModeMenu.training_mnemonic",
					 "ModeMenu.training_accessible_description", trainingModeActionObj);

		translationModeMI = createModeMenuItem(modeMenu, "ModeMenu.translation_label", "ModeMenu.translation_image", "ModeMenu.translation_mnemonic",
					 "ModeMenu.translation_accessible_description", translationModeActionObj);

		// ***** create commands menu 
		commandsMenu = (JMenu) menuBar.add(new JMenu(getString("CommandsMenu.label")));
		commandsMenu.setMnemonic(getMnemonic("CommandsMenu.mnemonic"));
		commandsMenu.getAccessibleContext().setAccessibleDescription(
			getString("CommandsMenu.accessible_description"));
	
		trainMI = createMenuItem(commandsMenu, "CommandsMenu.train_label", "CommandsMenu.train_image", "CommandsMenu.train_mnemonic",
					 "CommandsMenu.train_accessible_description", new TrainAction(this));
		trainMI.setEnabled(false);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0),
	 		"trainAction");
	 	getActionMap().put("trainAction", new TrainAction(this));

		translateMI = createMenuItem(commandsMenu, "CommandsMenu.translate_label", "CommandsMenu.translate_image", "CommandsMenu.translate_mnemonic",
					 "CommandsMenu.translate_accessible_description", new TranslateAction(this));
		translateMI.setEnabled(false);

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0),
	 		"translateAction");
	 	getActionMap().put("translateAction", new TranslateAction(this));

		// ***** create laf switcher menu 
		if (numSSs == 0) {
			lafMenu = (JMenu) menuBar.add(new JMenu(getString("LafMenu.laf_label")));
			lafMenu.setMnemonic(getMnemonic("LafMenu.laf_mnemonic"));
			lafMenu.getAccessibleContext().setAccessibleDescription(
				getString("LafMenu.laf_accessible_description"));

			mi = createLafMenuItem(lafMenu, "LafMenu.java_label", "LafMenu.java_mnemonic",
						 "LafMenu.java_accessible_description", metal);
			mi.setSelected(true); // this is the default l&f

			UIManager.LookAndFeelInfo[] lafInfo = UIManager.
											 getInstalledLookAndFeels();

			for (int counter = 0; counter < lafInfo.length; counter++) {
				String className = lafInfo[counter].getClassName();
				if (className == motif) {
					createLafMenuItem(lafMenu, "LafMenu.motif_label", "LafMenu.motif_mnemonic",
							"LafMenu.motif_accessible_description", motif);		
				} else if (className == windows) {
					createLafMenuItem(lafMenu, "LafMenu.windows_label", "LafMenu.windows_mnemonic",
							"LafMenu.windows_accessible_description", windows);
				} else if (className == gtk) {
					createLafMenuItem(lafMenu, "LafMenu.gtk_label", "LafMenu.gtk_mnemonic", 
							"LafMenu.gtk_accessible_description", gtk);
				}
			}
		}
		
		// ***** create help menu 
		helpMenu = (JMenu) menuBar.add(new JMenu(getString("HelpMenu.label")));
		helpMenu.setMnemonic(getMnemonic("HelpMenu.mnemonic"));
		helpMenu.getAccessibleContext().setAccessibleDescription(
			getString("HelpMenu.accessible_description"));
	
		mi = createMenuItem(helpMenu, "HelpMenu.help_label", "HelpMenu.help_image", "HelpMenu.help_mnemonic",
					 "HelpMenu.help_accessible_description", new HelpAction(helpViewerObj));

	 	// register key binding to save
	 	map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
	 	map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0),
	 		"helpAction");
	 	getActionMap().put("helpAction", new HelpAction(helpViewerObj));

		createMenuItem(helpMenu, "HelpMenu.about_label", null, "HelpMenu.about_mnemonic",
					 "HelpMenu.about_accessible_description", new AboutAction(this));
	

	
		// ***** create the multiscreen menu, if we have multiple screens
		GraphicsDevice[] screens = GraphicsEnvironment.
									getLocalGraphicsEnvironment().
									getScreenDevices();
		if (screens.length > 1) {

			JMenu multiScreenMenu = (JMenu) menuBar.add(new JMenu(
									 getString("MultiMenu.label")));

			multiScreenMenu.setMnemonic(getMnemonic("MultiMenu.mnemonic"));	
			multiScreenMenu.getAccessibleContext().setAccessibleDescription(
			 getString("MultiMenu.accessible_description"));

			createMultiscreenMenuItem(multiScreenMenu, MultiScreenAction.ALL_SCREENS);
			for (int i = 0; i < screens.length; i++) {
				createMultiscreenMenuItem(multiScreenMenu, i);
			}
		}
		return menuBar;
	}

	/**
	 * Creates a generic menu item
	 */
	private JMenuItem createMenuItem(JMenu menu, String label, String image,
		String mnemonic, String accessibleDescription, Action action) {
			
		JMenuItem mi = (JMenuItem) menu.add(new JMenuItem(getString(label)));
		
		if(image != null) {
			ImageIcon icon = createImageIcon(image, accessibleDescription);
			if(icon != null) {
				mi.setIcon(icon);
			}
		}
		
		mi.setMnemonic(getMnemonic(mnemonic));
		mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));

		ActionListener cursorDoIt = CursorController.createListener(GUI.getFrame(), action);
		mi.addActionListener(cursorDoIt);
//		mi.addActionListener(action);
		
		if(action == null) {
			mi.setEnabled(false);
		}
		return mi;
	}

	/**
	 * Creates a JRadioButtonMenuItem for the Mode menu
	 */
	private JMenuItem createModeMenuItem(JMenu menu, String label, String image, String mnemonic,
		String accessibleDescription, Action action) {

		JMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label)));

		modeMenuGroup.add(mi);
	
		if(image != null) {
			ImageIcon icon = createImageIcon(image, accessibleDescription);
			if(icon != null) {
				mi.setIcon(icon);
			}
		}
		
		mi.setMnemonic(getMnemonic(mnemonic));
		mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));

		ActionListener cursorDoIt = CursorController.createListener(GUI.getFrame(), action);
		mi.addActionListener(cursorDoIt);
//		mi.addActionListener(action);
	
		if(action == null) {
			mi.setEnabled(false);
		}
		return mi;
	}

	/**
	 * Creates a JRadioButtonMenuItem for the Look and Feel menu
	 */
	private JMenuItem createLafMenuItem(JMenu menu, String label, String mnemonic,
		String accessibleDescription, String laf) {
		JMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(getString(label)));
		lafMenuGroup.add(mi);
		mi.setMnemonic(getMnemonic(mnemonic));
		mi.getAccessibleContext().setAccessibleDescription(getString(accessibleDescription));

		ActionListener cursorDoIt = CursorController.createListener(GUI.getFrame(), new ChangeLookAndFeelAction(this, laf));
		mi.addActionListener(cursorDoIt);
//		mi.addActionListener(new ChangeLookAndFeelAction(this, laf));
	
		mi.setEnabled(isAvailableLookAndFeel(laf));

		return mi;
	}

	/**
	 * Creates a multi-screen menu item
	 */
	public JMenuItem createMultiscreenMenuItem(JMenu menu, int screen) {
		JMenuItem mi = null;
		if (screen == MultiScreenAction.ALL_SCREENS) {
			mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.all_label")));
			mi.setMnemonic(getMnemonic("MultiMenu.all_mnemonic"));
			mi.getAccessibleContext().setAccessibleDescription(getString(
																 "MultiMenu.all_accessible_description"));
		}
		else {
			mi = (JMenuItem) menu.add(new JMenuItem(getString("MultiMenu.single_label") + " " +
																								 screen));
			mi.setMnemonic(KeyEvent.VK_0 + screen);
			mi.getAccessibleContext().setAccessibleDescription(getString(
												 "MultiMenu.single_accessible_description") + " " + screen);
																							
		}

		ActionListener cursorDoIt = CursorController.createListener(GUI.getFrame(), new MultiScreenAction(this, screen));
		mi.addActionListener(cursorDoIt);
//		mi.addActionListener(new MultiScreenAction(this, screen));

		return mi;
	}

	/**
	 * Creates the toolbar
	 */
	 public void createToolBar() {
 		// do the following on the gui thread
		SwingUtilities.invokeLater(new GUIRunnable(this, null) {
			public void run() {
				//file
				buttonNew = gui.getToolBar().add(new NewAction(gui));
				buttonNew.setText(null);
				buttonNew.setToolTipText(getString("FileMenu.new_accessible_description"));
				buttonNew.setIcon(createImageIcon("FileMenu.new_image", "FileMenu.new_accessible_description"));
				buttonNew.setEnabled(false);
				buttonOpen = gui.getToolBar().add(new OpenAction(gui));
				buttonOpen.setText(null);
				buttonOpen.setToolTipText(getString("FileMenu.open_accessible_description"));
				buttonOpen.setIcon(createImageIcon("FileMenu.open_image", "FileMenu.open_accessible_description"));
				buttonOpen.setEnabled(false);
				buttonSave = gui.getToolBar().add(new SaveAction(gui));
				buttonSave.setText(null);
				buttonSave.setToolTipText(getString("FileMenu.save_accessible_description"));
				buttonSave.setIcon(createImageIcon("FileMenu.save_image", "FileMenu.save_accessible_description"));
				buttonSave.setEnabled(false);
				buttonSaveAs = gui.getToolBar().add(new SaveAsAction(gui));
				buttonSaveAs.setText(null);
				buttonSaveAs.setToolTipText(getString("FileMenu.saveas_accessible_description"));
				buttonSaveAs.setIcon(createImageIcon("FileMenu.saveas_image", "FileMenu.saveas_accessible_description"));
				buttonSaveAs.setEnabled(false);
				
				gui.getToolBar().addSeparator();
				
				//edit
				buttonCut = gui.getToolBar().add(new CutAction(gui));
				buttonCut.setText(null);
				buttonCut.setToolTipText(getString("EditMenu.cut_accessible_description"));
				buttonCut.setIcon(createImageIcon("EditMenu.cut_image", "EditMenu.cut_accessible_description"));
				buttonCut.setEnabled(false);
				buttonCopy = gui.getToolBar().add(new CopyAction(gui));
				buttonCopy.setText(null);
				buttonCopy.setToolTipText(getString("EditMenu.copy_accessible_description"));
				buttonCopy.setIcon(createImageIcon("EditMenu.copy_image", "EditMenu.copy_accessible_description"));
				buttonCopy.setEnabled(false);
				buttonPaste = gui.getToolBar().add(new PasteAction(gui));
				buttonPaste.setText(null);
				buttonPaste.setToolTipText(getString("EditMenu.paste_accessible_description"));
				buttonPaste.setIcon(createImageIcon("EditMenu.paste_image", "EditMenu.paste_accessible_description"));
				buttonPaste.setEnabled(false);
				
				gui.getToolBar().addSeparator();
				
				//view				
				buttonLexicon = gui.getToolBar().addToggleButton(lexiconActionObj);
				buttonLexicon.setSelected(true);
				buttonLexicon.setText(null);
				buttonLexicon.setToolTipText(getString("ViewMenu.lexicon_accessible_description"));
				buttonLexicon.setIcon(createImageIcon("ViewMenu.lexicon_image", "ViewMenu.lexicon_accessible_description"));
				buttonChunks = gui.getToolBar().addToggleButton(chunksActionObj);
				buttonChunks.setSelected(false);
				buttonChunks.setText(null);
				buttonChunks.setToolTipText(getString("ViewMenu.chunks_accessible_description"));
				buttonChunks.setIcon(createImageIcon("ViewMenu.chunks_image", "ViewMenu.chunks_accessible_description"));
				buttonTemplates = gui.getToolBar().addToggleButton(templatesActionObj);
				buttonTemplates.setSelected(false);
				buttonTemplates.setText(null);
				buttonTemplates.setToolTipText(getString("ViewMenu.templates_accessible_description"));
				buttonTemplates.setIcon(createImageIcon("ViewMenu.templates_image", "ViewMenu.templates_accessible_description"));
				buttonUnused = gui.getToolBar().addToggleButton(unusedActionObj);
				buttonUnused.setSelected(false);
				buttonUnused.setText(null);
				buttonUnused.setToolTipText(getString("ViewMenu.unused_accessible_description"));
				buttonUnused.setIcon(createImageIcon("ViewMenu.unused_image", "ViewMenu.unused_accessible_description"));
				buttonStatus = gui.getToolBar().addToggleButton(statusActionObj);
				buttonStatus.setSelected(true);
				buttonStatus.setText(null);
				buttonStatus.setToolTipText(getString("ViewMenu.status_accessible_description"));
				buttonStatus.setIcon(createImageIcon("ViewMenu.status_image", "ViewMenu.status_accessible_description"));
				
				gui.getToolBar().addSeparator();

				//mode
				buttonTrainingMode = gui.getToolBar().addToggleButton(trainingModeActionObj);
				gui.getToolBarGroup().add(buttonTrainingMode);
				buttonTrainingMode.setText(null);
				buttonTrainingMode.setToolTipText(getString("ModeMenu.training_accessible_description"));
				buttonTrainingMode.setIcon(createImageIcon("ModeMenu.training_image", "ModeMenu.training_accessible_description"));
				buttonTranslationMode = gui.getToolBar().addToggleButton(translationModeActionObj);
				gui.getToolBarGroup().add(buttonTranslationMode);
				buttonTranslationMode.setText(null);
				buttonTranslationMode.setToolTipText(getString("ModeMenu.translation_accessible_description"));
				buttonTranslationMode.setIcon(createImageIcon("ModeMenu.translation_image", "ModeMenu.translation_accessible_description"));
				
				gui.getToolBar().addSeparator();

				//commands
				buttonTrain = gui.getToolBar().add(new TrainAction(gui));
				buttonTrain.setText(null);
				buttonTrain.setToolTipText(getString("CommandsMenu.train_accessible_description"));
				buttonTrain.setIcon(createImageIcon("CommandsMenu.train_image", "CommandsMenu.train_accessible_description"));
				buttonTrain.setEnabled(false);
				buttonTranslate = gui.getToolBar().add(new TranslateAction(gui));
				buttonTranslate.setText(null);
				buttonTranslate.setToolTipText(getString("CommandsMenu.translate_accessible_description"));
				buttonTranslate.setIcon(createImageIcon("CommandsMenu.translate_image", "CommandsMenu.translate_accessible_description"));
				buttonTranslate.setEnabled(false);
				
				gui.getToolBar().addSeparator();
				
				buttonTrace = gui.getToolBar().add(new TraceAction(gui));
				buttonTrace.setEnabled(false);
				buttonTrace.setText(null);
				buttonTrace.setToolTipText(getString("ViewMenu.trace_accessible_description"));
				buttonTrace.setIcon(createImageIcon("ViewMenu.trace_image", "ViewMenu.trace_accessible_description"));

				gui.getToolBar().addSeparator();

				//help				
				buttonHelp = gui.getToolBar().add(helpActionObj);
				buttonHelp.setText(null);
				buttonHelp.setToolTipText(getString("HelpMenu.help_accessible_description"));
				buttonHelp.setIcon(createImageIcon("HelpMenu.help_image", "HelpMenu.help_accessible_description"));
			}
		});
	 }
	 
	//Docking and floating windows
	private JPanel createCenterPanel() {

		JPanel panel = new JPanel(new BorderLayout(0, 0));
		panel.setBorder(new EmptyBorder(5, 5, 5, 5));

		Viewport viewport = new Viewport();
		panel.add(viewport, BorderLayout.CENTER);

		modePage = createModePage(new DefaultMode().getViewerPanel());
		viewLexicon = createView("lexicon.view", getString("LexiconViewer.name"), lexiconViewerObj.getViewerPanel());
		viewChunks = createView("chunks.view", getString("ChunksViewer.name"), chunksViewerObj.getViewerPanel());
		viewTemplates = createView("templates.view", getString("TemplatesViewer.name"), templatesViewerObj.getViewerPanel());
		viewUnused = createView("unused.view", getString("UnusedSentencesViewer.name"), unusedViewerObj.getViewerPanel());
		viewStatus = createView("status.view", getString("StatusViewer.name"), statusViewerObj.getViewerPanel());

		viewport.dock(modePage);
		modePage.dock(viewLexicon, "EAST", .28f);
		viewLexicon.dock(viewChunks, "SOUTH", .73f);
		viewChunks.dock(viewTemplates, "SOUTH", .68f);
		viewTemplates.dock(viewUnused, "SOUTH", .53f);
		modePage.dock(viewStatus, "SOUTH", .3f);

		return panel;
	}

	private View createView(String id, String text, JPanel panel) {
		View view = new View(id, text);
		//view.addAction("close");
		view.addAction("pin");

		if(panel == null) {
			JPanel tmpPanel = new JPanel();
			tmpPanel.setBorder(new LineBorder(Color.GRAY, 1));
			view.setContentPane(tmpPanel);
		}else {
			panel.setBorder(new LineBorder(Color.GRAY, 1));
			view.setContentPane(panel);
		}
		
		return view;
	}

	protected View createModePage(JPanel panel) {
		String id = "modePage";
		View view = new View(id, "Mode", null);
		view.setTerritoryBlocked("center", true);
		view.setTitlebar(null);
		view.setContentPane(panel);
		return view;
	}

	/**
	 * Bring up the GUI demo by showing the frame (only
	 * applicable if coming up as an application, not an applet);
	 */
	public void showGUI() {
		if(getFrame() != null) {
			// put gui in a frame and show it
			JFrame f = getFrame();
			f.setTitle(getString("Frame.title"));
			ImageIcon icon = createImageIcon("Icon.image","Icon.accessible_description");
			if(icon != null) {
				f.setIconImage(icon.getImage());
			}
			f.getContentPane().add(this, BorderLayout.CENTER);
			f.pack();
	
			Rectangle screenRect = f.getGraphicsConfiguration().getBounds();
			Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(
					f.getGraphicsConfiguration());

			// Make sure we don't place the demo off the screen.
			int centerWidth = screenRect.width < f.getSize().width ?
					screenRect.x :
					screenRect.x + screenRect.width/2 - f.getSize().width/2;
			int centerHeight = screenRect.height < f.getSize().height ?
					screenRect.y :
					screenRect.y + screenRect.height/2 - f.getSize().height/2;

			centerHeight = centerHeight < screenInsets.top ?
					screenInsets.top : centerHeight;

			f.setLocation(centerWidth, centerHeight);
			f.setVisible(true);
			numSSs++;
			guis.add(this);
		} 
	}

	/**
	 * Show the spash screen while the rest of the demo loads
	 */
	public void createSplashScreen() {
		ImageIcon icon = createImageIcon("Splash.image", "Splash.accessible_description");
	
		if(icon != null) {
			splashLabel = new JLabel(icon);
			splashScreen = new JWindow(getFrame());
			splashScreen.getContentPane().add(splashLabel);
			splashScreen.pack();
			Rectangle screenRect = getFrame().getGraphicsConfiguration().getBounds();
			splashScreen.setLocation(
			screenRect.x + screenRect.width/2 - splashScreen.getSize().width/2,
			screenRect.y + screenRect.height/2 - splashScreen.getSize().height/2);
		}
	}

	public void showSplashScreen() {
		splashScreen.setVisible(true);
	}

	/**
	 * pop down the spash screen
	 */
	public void hideSplash() {
		splashScreen.setVisible(false);
		splashScreen = null;
		splashLabel = null;
	}

	// *******************************************************
	// ****************** Utility Methods ********************
	// *******************************************************
	
	/**
	 * Returns the frame instance
	 */
	public static JFrame getFrame() {
		return frame;
	}

		/**
	* A utility function that layers on top of the LookAndFeel's
	* isSupportedLookAndFeel() method. Returns true if the LookAndFeel
	* is supported. Returns false if the LookAndFeel is not supported
	* and/or if there is any kind of error checking if the LookAndFeel
	* is supported.
	*
	* The L&F menu will use this method to detemine whether the various
	* L&F options should be active or inactive.
	*
	*/
	protected boolean isAvailableLookAndFeel(String laf) {
			try { 
			 Class lnfClass = Class.forName(laf);
			 LookAndFeel newLAF = (LookAndFeel)(lnfClass.newInstance());
			 return newLAF.isSupportedLookAndFeel();
			} catch(Exception e) { // If ANYTHING weird happens, return false
			 return false;
			}
	}

	/**
	 * Returns the menubar
	 */
	public JMenuBar getMenuBar() {
		return menuBar;
	}

	/**
	 * Returns the toolbar
	 */
	public ToggleButtonToolBar getToolBar() {
		return toolbar;
	}

	/**
	 * Returns the toolbar button group
	 */
	public ButtonGroup getToolBarGroup() {
		return toolbarModeGroup;
	}

	/**
	 * Returns the content pane wether we're in an applet
	 * or application
	 */
	public Container getContentPane() {
		if(contentPane == null) {
			if(getFrame() != null) {
				contentPane = getFrame().getContentPane();
			}
		}
		return contentPane;
	}

	/**
	 * Create a frame for GUI to reside in if brought up
	 * as an application.
	 */
	public static JFrame createFrame(GraphicsConfiguration gc) {
		JFrame frame = new JFrame(gc);
		if (numSSs == 0) {
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		} else {
			WindowListener l = new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
						numSSs--;
						guis.remove(this);
				}
			};
			frame.addWindowListener(l);
		}
		return frame;
	}


	/**
	 * Set the tip 
	 */
	public void setTip(String s) {
		// do the following on the gui thread
		SwingUtilities.invokeLater(new GUIRunnable(this, s) {
			public void run() {
				gui.tipField.setText((String) obj);
			}
		});
	}

	/**
	 * Clears the status text area
	 */
	public static void clearStatus() {
/*
		// do the following on the gui thread
		SwingUtilities.invokeLater(new GUIRunnable(this, null) {
			public void run() {
				if(gui.getStatusViewer() != null) {
					gui.getStatusViewer().clearStatus();
				}
			}
		});
*/
		if(getStatusViewer() != null) {
			getStatusViewer().clearStatus();
		}
	}

	/**
	 * Append to the status text area
	 */
	public static void appendToStatus(String s) {
/*
		// do the following on the gui thread
		SwingUtilities.invokeLater(new GUIRunnable(this, s) {
			public void run() {
				if(gui.getStatusViewer() != null) {
					gui.getStatusViewer().appendToStatus((String) obj);
				}
			}
		});
*/
		if(getStatusViewer() != null) {
			getStatusViewer().appendToStatus(s);
		}
	}

	/**
	 * This method returns a string from the demo's resource bundle.
	 */
	public String getString(String key) {
		String value = null;
		try {
			value = getResourceBundle().getString(key);
		} catch (MissingResourceException e) {
			System.out.println("java.util.MissingResourceException: Couldn't find value for: " + key);
		}
		if(value == null) {
			value = "Could not find resource: " + key + "	";
		}
		return value;
	}

	/**
	 * Returns the resource bundle associated with this demo. Used
	 * to get accessable and internationalized strings.
	 */
	public ResourceBundle getResourceBundle() {
		if(bundle == null) {
			bundle = ResourceBundle.getBundle("resources.gui");
		}
		return bundle;
	}

	/**
	 * Returns a mnemonic from the resource bundle. Typically used as
	 * keyboard shortcuts in menu items.
	 */
	public char getMnemonic(String key) {
		return (getString(key)).charAt(0);
	}

	/**
	 * Creates an icon from an image contained in the "images" directory.
	 */
	public ImageIcon createImageIcon(String filename, String description) {
		ImageIcon icon = null;
		if(filename != null) {
			String path = "/resources/images/" + getString(filename);
			URL url = null;
			
			try{
				url = getClass().getResource(path);
			} catch (MissingResourceException e) {
				System.out.println("java.util.MissingResourceException: Couldn't find image in: " + path);
			}
			
			if(url != null) {
				icon = new ImageIcon(url, getString(description)); 
			}else {
				System.out.println("java.util.MissingResourceException: Couldn't find image in: " + path);
			}
	
		}
		return icon;
	}

	private void updateThisGUI() {
		JFrame frame = getFrame();
		if (frame == null) {
			SwingUtilities.updateComponentTreeUI(this);
		} else {
			SwingUtilities.updateComponentTreeUI(frame);
		}

		if (aboutBox != null) {
			SwingUtilities.updateComponentTreeUI(aboutBox);
		}
	}

	/**
	 * Sets the current L&F on each demo module
	 */
	private void updateLookAndFeel() {
		try {
			UIManager.setLookAndFeel(currentLookAndFeel);
			for (int i = 0; i < guis.size(); i++) {
				((GUI)guis.get(i)).updateThisGUI();
			}
		} catch (Exception ex) {
			System.out.println("Failed loading L&F: " + currentLookAndFeel);
			System.out.println(ex);
		}
	}

	public View getModePage() {
		return modePage;
	}

	public JButton getButtonNew() {
		return buttonNew;
	}

	public JButton getButtonOpen() {
		return buttonOpen;
	}

	public JButton getButtonSave() {
		return buttonSave;
	}

	public JButton getButtonSaveAs() {
		return buttonSaveAs;
	}

	public JButton getButtonCut() {
		return buttonCut;
	}

	public JButton getButtonCopy() {
		return buttonCopy;
	}

	public JButton getButtonPaste() {
		return buttonPaste;
	}

	public JButton getButtonTrain() {
		return buttonTrain;
	}

	public JButton getButtonTranslate() {
		return buttonTranslate;
	}

	public JToggleButton getButtonTrainingMode() {
		return buttonTrainingMode;
	}

	public JToggleButton getButtonTranslationMode() {
		return buttonTranslationMode;
	}

	public JToggleButton getButtonLexicon() {
		return buttonLexicon;
	}

	public JToggleButton getButtonChunks() {
		return buttonChunks;
	}

	public JToggleButton getButtonTemplates() {
		return buttonTemplates;
	}

	public JToggleButton getButtonUnused() {
		return buttonUnused;
	}

	public JToggleButton getButtonStatus() {
		return buttonStatus;
	}

	public JButton getButtonTrace() {
		return buttonTrace;
	}

	public JMenuItem getNewMI() {
		return newMI;
	}

	public JMenuItem getOpenMI() {
		return openMI;
	}

	public JMenuItem getSaveMI() {
		return saveMI;
	}

	public JMenuItem getSaveAsMI() {
		return saveAsMI;
	}

	public JMenuItem getCutMI() {
		return cutMI;
	}

	public JMenuItem getCopyMI() {
		return copyMI;
	}

	public JMenuItem getPasteMI() {
		return pasteMI;
	}

	public JMenuItem getTrainingModeMI() {
		return trainingModeMI;
	}

	public JMenuItem getTranslationModeMI() {
		return translationModeMI;
	}

	public JMenuItem getTrainMI() {
		return trainMI;
	}

	public JMenuItem getTranslateMI() {
		return translateMI;
	}

	public JMenuItem getTraceMI() {
		return traceMI;
	}

	public Object getMode() {
/*
		if(trainingModeViewerObj != null) {
			return trainingModeViewerObj;
		}else if(translationModeViewerObj != null) {
			return translationModeViewerObj;
		}else {
			return null;
		}
*/
		if(mode.equals(MODE_TRAINING)) {
			return trainingModeViewerObj;
		}else if(mode.equals(MODE_TRANSLATION)) {
			return translationModeViewerObj;
		}else {
			return null;
		}
	}

	public void setMode(Object modeViewer) {
/*
//		if(modeViewer.getClass().getName().equals("TrainingModeViewer")) {
		if(modeViewer instanceof TrainingModeViewer) {
			trainingModeViewerObj = (TrainingModeViewer) modeViewer;
			translationModeViewerObj = null;
//		}else if(modeViewer.getClass().getName().equals("TranslationModeViewer")) {
		}else if(modeViewer instanceof TranslationModeViewer) {
			trainingModeViewerObj = null;
			translationModeViewerObj = (TranslationModeViewer) modeViewer;
		}
*/
		if(modeViewer instanceof TrainingModeViewer) {
			trainingModeViewerObj = (TrainingModeViewer) modeViewer;
			mode = MODE_TRAINING;
		}else if(modeViewer instanceof TranslationModeViewer) {
			translationModeViewerObj = (TranslationModeViewer) modeViewer;
			mode = MODE_TRANSLATION;
		}
	}

	public LexiconViewer getLexiconViewer() {
		return lexiconViewerObj;
	}

	public ChunksViewer getChunksViewer() {
		return chunksViewerObj;
	}

	public TemplatesViewer getTemplatesViewer() {
		return templatesViewerObj;
	}

	public UnusedSentencesViewer getUnusedViewer() {
		return unusedViewerObj;
	}

	public static StatusViewer getStatusViewer() {
		return statusViewerObj;
	}

	public View getChunksView() {
		return viewChunks;
	}

	public View getTemplatesView() {
		return viewTemplates;
	}

	public View getUnusedView() {
		return viewUnused;
	}

	public static Timer getTimer() {
		return timer;
	}

	public static JProgressBar getProgressBar() {
		return progressBar;
	}

	public void refreshTable(Object viewer) {
//		if(viewer.getClass().getName().equals("LexiconViewer")) {
		if(viewer instanceof LexiconViewer) {
			DockingManager.close(viewLexicon);
			lexiconViewerObj = new LexiconViewer(this);
			lexiconViewerObj.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
			viewLexicon.setContentPane(lexiconViewerObj.getViewerPanel());
			DockingManager.display(viewLexicon);
//		}else if(viewer.getClass().getName().equals("ChunksViewer")) {
		}else if(viewer instanceof ChunksViewer) {
			DockingManager.close(viewChunks);
			chunksViewerObj = new ChunksViewer(this);
			chunksViewerObj.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
			viewChunks.setContentPane(chunksViewerObj.getViewerPanel());
			DockingManager.display(viewChunks);
//		}else if(viewer.getClass().getName().equals("TemplatesViewer")) {
		}else if(viewer instanceof TemplatesViewer) {
			DockingManager.close(viewTemplates);
			templatesViewerObj = new TemplatesViewer(this);
			templatesViewerObj.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
			viewTemplates.setContentPane(templatesViewerObj.getViewerPanel());
			DockingManager.display(viewTemplates);
		}else if(viewer instanceof UnusedSentencesViewer) {
			DockingManager.close(viewUnused);
			unusedViewerObj = new UnusedSentencesViewer(this);
			unusedViewerObj.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
			viewUnused.setContentPane(unusedViewerObj.getViewerPanel());
			DockingManager.display(viewUnused);
		}
	}
	
	// *******************************************************
	// **************	 ToggleButtonToolbar	*****************
	// *******************************************************
	static Insets zeroInsets = new Insets(1,1,1,1);
	protected class ToggleButtonToolBar extends JToolBar {
		public ToggleButtonToolBar() {
			super();
		}
	
		JToggleButton addToggleButton(Action a) {
			JToggleButton tb = new JToggleButton(
				(String)a.getValue(Action.NAME),
				(Icon)a.getValue(Action.SMALL_ICON)
			);
			tb.setMargin(zeroInsets);
			tb.setText(null);
			tb.setEnabled(a.isEnabled());
			tb.setToolTipText((String)a.getValue(Action.SHORT_DESCRIPTION));
			tb.setAction(a);
			add(tb);
			return tb;
		}
	}

	// *******************************************************
	// *********	ToolBar Panel / Docking Listener ***********
	// *******************************************************
	class ToolBarPanel extends JPanel implements ContainerListener {
	
		public boolean contains(int x, int y) {
			Component c = getParent();
			if (c != null) {
				Rectangle r = c.getBounds();
				return (x >= 0) && (x < r.width) && (y >= 0) && (y < r.height);
			}else {
				return super.contains(x,y);
			}
		}
	
		public void componentAdded(ContainerEvent e) {
			Container c = e.getContainer().getParent();
			if (c != null) {
				c.getParent().validate();
				c.getParent().repaint();		
			}
		}
	
		public void componentRemoved(ContainerEvent e) {
			Container c = e.getContainer().getParent();
			if (c != null) {
				c.getParent().validate();
				c.getParent().repaint();
			}
		}
	}

	// *******************************************************
	// ******************	 Runnables	***********************
	// *******************************************************

	/**
	 * Generic GUI runnable. This is intended to run on the
	 * AWT gui event thread so as not to muck things up by doing
	 * gui work off the gui thread. Accepts a GUI and an Object
	 * as arguments, which gives subtypes of this class the two
	 * "must haves" needed in most runnables for this demo.
	 */
	class GUIRunnable implements Runnable {
		protected GUI gui;
		protected Object obj;
		
		public GUIRunnable(GUI gui, Object obj) {
			this.gui = gui;
			this.obj = obj;
		}
	
		public void run() {
			
		}
	}

	// *******************************************************
	// ********************	 Actions   ***********************
	// *******************************************************
	class NewAction extends AbstractAction {
		GUI gui;
		
		public NewAction(GUI gui) {
			super("NewAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				TrainingModeViewer trainingModeViewer = null;
				TranslationModeViewer translationModeViewer = null;
//				if(gui.getMode().getClass().getName().equals("TrainingModeViewer")) {
				if(gui.getMode() instanceof TrainingModeViewer) {
					trainingModeViewer = (TrainingModeViewer) gui.getMode();
//				}else if(gui.getMode().getClass().getName().equals("TranslationModeViewer")) {
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					translationModeViewer = (TranslationModeViewer) gui.getMode();
				}
				if(trainingModeViewer != null) {
					if(trainingModeViewer.getMode() == 'S') {
						trainingModeViewer.newAction(trainingModeViewer.getSourceTextArea(), "Source: ");
					}else if(trainingModeViewer.getMode() == 'T') {
						trainingModeViewer.newAction(trainingModeViewer.getTargetTextArea(), "Target: ");
					}
				}else if(translationModeViewer != null) {
					translationModeViewer.newAction(translationModeViewer.getSourceTextArea());
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class OpenAction extends AbstractAction {
		GUI gui;
		
		public OpenAction(GUI gui) {
			super("OpenAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				TrainingModeViewer trainingModeViewer = null;
				TranslationModeViewer translationModeViewer = null;
	//			if(gui.getMode().getClass().getName().equals("TrainingModeViewer")) {
				if(gui.getMode() instanceof TrainingModeViewer) {
					trainingModeViewer = (TrainingModeViewer) gui.getMode();
	//			}else if(gui.getMode().getClass().getName().equals("TranslationModeViewer")) {
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					translationModeViewer = (TranslationModeViewer) gui.getMode();
				}
				if(trainingModeViewer != null) {
					if(trainingModeViewer.getMode() == 'S') {
						trainingModeViewer.openAction(trainingModeViewer.getSourceTextArea(), "Source: ");
					}else if(trainingModeViewer.getMode() == 'T') {
						trainingModeViewer.openAction(trainingModeViewer.getTargetTextArea(), "Target: ");
					}
				}else if(translationModeViewer != null) {
					translationModeViewer.openAction(translationModeViewer.getSourceTextArea());
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class SaveAction extends AbstractAction {
		GUI gui;
		
		public SaveAction(GUI gui) {
			super("SaveAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				TrainingModeViewer trainingModeViewer = null;
				TranslationModeViewer translationModeViewer = null;
	//			if(gui.getMode().getClass().getName().equals("TrainingModeViewer")) {
				if(gui.getMode() instanceof TrainingModeViewer) {
					trainingModeViewer = (TrainingModeViewer) gui.getMode();
	//			}else if(gui.getMode().getClass().getName().equals("TranslationModeViewer")) {
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					translationModeViewer = (TranslationModeViewer) gui.getMode();
				}
				if(trainingModeViewer != null) {
					if(trainingModeViewer.getMode() == 'S') {
						trainingModeViewer.saveAction(trainingModeViewer.getSourceTextArea(), "Source: ");
					}else if(trainingModeViewer.getMode() == 'T') {
						trainingModeViewer.saveAction(trainingModeViewer.getTargetTextArea(), "Target: ");
					}
				}else if(translationModeViewer != null) {
					if(translationModeViewer.getMode() == 'S') {
						translationModeViewer.saveAction(translationModeViewer.getSourceTextArea(), "Source: ");
					}else if(translationModeViewer.getMode() == 'T') {
						translationModeViewer.saveAction(translationModeViewer.getTranslatedTextArea(), "Translation: ");
					}
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class SaveAsAction extends AbstractAction {
		GUI gui;
		
		public SaveAsAction(GUI gui) {
			super("SaveAsAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				TrainingModeViewer trainingModeViewer = null;
				TranslationModeViewer translationModeViewer = null;
	//			if(gui.getMode().getClass().getName().equals("TrainingModeViewer")) {
				if(gui.getMode() instanceof TrainingModeViewer) {
					trainingModeViewer = (TrainingModeViewer) gui.getMode();
	//			}else if(gui.getMode().getClass().getName().equals("TranslationModeViewer")) {
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					translationModeViewer = (TranslationModeViewer) gui.getMode();
				}
				if(trainingModeViewer != null) {
					if(trainingModeViewer.getMode() == 'S') {
						trainingModeViewer.saveAsAction(trainingModeViewer.getSourceTextArea(), "Source: ");
					}else if(trainingModeViewer.getMode() == 'T') {
						trainingModeViewer.saveAsAction(trainingModeViewer.getTargetTextArea(), "Target: ");
					}
				}else if(translationModeViewer != null) {
					if(translationModeViewer.getMode() == 'S') {
						translationModeViewer.saveAsAction(translationModeViewer.getSourceTextArea(), "Source: ");
					}else if(translationModeViewer.getMode() == 'T') {
						translationModeViewer.saveAsAction(translationModeViewer.getTranslatedTextArea(), "Translation: ");
					}
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class ExitAction extends AbstractAction {
		GUI gui;
		protected ExitAction(GUI gui) {
			super("ExitAction");
			this.gui = gui;
		}

		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	}
	
	class CutAction extends AbstractAction {
		GUI gui;
		
		public CutAction(GUI gui) {
			super("CutAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				TrainingModeViewer trainingModeViewer = null;
				TranslationModeViewer translationModeViewer = null;
	//			if(gui.getMode().getClass().getName().equals("TrainingModeViewer")) {
				if(gui.getMode() instanceof TrainingModeViewer) {
					trainingModeViewer = (TrainingModeViewer) gui.getMode();
	//			}else if(gui.getMode().getClass().getName().equals("TranslationModeViewer")) {
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					translationModeViewer = (TranslationModeViewer) gui.getMode();
				}
				if(trainingModeViewer != null) {
					if(trainingModeViewer.getMode() == 'S') {
						trainingModeViewer.cutAction(trainingModeViewer.getSourceTextArea());
					}else if(trainingModeViewer.getMode() == 'T') {
						trainingModeViewer.cutAction(trainingModeViewer.getTargetTextArea());
					}
				}else if(translationModeViewer != null) {
					if(translationModeViewer.getMode() == 'S') {
						translationModeViewer.cutAction(translationModeViewer.getSourceTextArea());
					}else if(translationModeViewer.getMode() == 'T') {
						translationModeViewer.cutAction(translationModeViewer.getTranslatedTextArea());
					}
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}
	
	class CopyAction extends AbstractAction {
		GUI gui;
		
		public CopyAction(GUI gui) {
			super("CopyAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				TrainingModeViewer trainingModeViewer = null;
				TranslationModeViewer translationModeViewer = null;
	//			if(gui.getMode().getClass().getName().equals("TrainingModeViewer")) {
				if(gui.getMode() instanceof TrainingModeViewer) {
					trainingModeViewer = (TrainingModeViewer) gui.getMode();
	//			}else if(gui.getMode().getClass().getName().equals("TranslationModeViewer")) {
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					translationModeViewer = (TranslationModeViewer) gui.getMode();
				}
				if(trainingModeViewer != null) {
					if(trainingModeViewer.getMode() == 'S') {
						trainingModeViewer.copyAction(trainingModeViewer.getSourceTextArea());
					}else if(trainingModeViewer.getMode() == 'T') {
						trainingModeViewer.copyAction(trainingModeViewer.getTargetTextArea());
					}
				}else if(translationModeViewer != null) {
					if(translationModeViewer.getMode() == 'S') {
						translationModeViewer.copyAction(translationModeViewer.getSourceTextArea());
					}else if(translationModeViewer.getMode() == 'T') {
						translationModeViewer.copyAction(translationModeViewer.getTranslatedTextArea());
					}
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}
	
	class PasteAction extends AbstractAction {
		GUI gui;
		
		public PasteAction(GUI gui) {
			super("PasteAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				TrainingModeViewer trainingModeViewer = null;
				TranslationModeViewer translationModeViewer = null;
//				if(gui.getMode().getClass().getName().equals("TrainingModeViewer")) {
				if(gui.getMode() instanceof TrainingModeViewer) {
					trainingModeViewer = (TrainingModeViewer) gui.getMode();
//				}else if(gui.getMode().getClass().getName().equals("TranslationModeViewer")) {
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					translationModeViewer = (TranslationModeViewer) gui.getMode();
				}
				if(trainingModeViewer != null) {
					if(trainingModeViewer.getMode() == 'S') {
						trainingModeViewer.pasteAction(trainingModeViewer.getSourceTextArea());
					}else if(trainingModeViewer.getMode() == 'T') {
						trainingModeViewer.pasteAction(trainingModeViewer.getTargetTextArea());
					}
				}else if(translationModeViewer != null) {
					if(translationModeViewer.getMode() == 'S') {
						translationModeViewer.pasteAction(translationModeViewer.getSourceTextArea());
					}else if(translationModeViewer.getMode() == 'T') {
						translationModeViewer.pasteAction(translationModeViewer.getTranslatedTextArea());
					}
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class ModeAction extends AbstractAction {
		GUI gui;
		boolean bTrain;
		
		public ModeAction(GUI gui, boolean bTrain) {
			super("ModeAction");
			this.gui = gui;
			this.bTrain = bTrain;
		}

		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				DockingManager.close(gui.getModePage());
				if(bTrain) {
					TrainingModeViewer trainingModeViewer = new TrainingModeViewer();
					trainingModeViewer.setMode('T');
					gui.setMode(trainingModeViewer);
					gui.getModePage().setContentPane(trainingModeViewer.getViewerPanel());
					gui.getTrainingModeMI().setSelected(true);
					gui.getTranslationModeMI().setSelected(false);
					gui.getButtonTrainingMode().setSelected(true);
					gui.getTrainMI().setEnabled(true);
					gui.getButtonTrain().setEnabled(true);
					gui.getTranslateMI().setEnabled(false);
					gui.getButtonTranslate().setEnabled(false);
					gui.setTip(gui.getString("Status.trainTip"));
				}else {
					TranslationModeViewer translationModeViewer = new TranslationModeViewer();
					gui.setMode(translationModeViewer);
					gui.getModePage().setContentPane(translationModeViewer.getViewerPanel());
					gui.getTrainingModeMI().setSelected(false);
					gui.getTranslationModeMI().setSelected(true);
					gui.getButtonTranslationMode().setSelected(true);
					gui.getTrainMI().setEnabled(false);
					gui.getButtonTrain().setEnabled(false);
					gui.getTranslateMI().setEnabled(true);
					gui.getButtonTranslate().setEnabled(true);
					gui.setTip(gui.getString("Status.translateTip"));
				}
				gui.getNewMI().setEnabled(true);
				gui.getButtonNew().setEnabled(true);
				gui.getOpenMI().setEnabled(true);
				gui.getButtonOpen().setEnabled(true);
				gui.getSaveMI().setEnabled(true);
				gui.getButtonSave().setEnabled(true);
				gui.getSaveAsMI().setEnabled(true);
				gui.getButtonSaveAs().setEnabled(true);
				gui.getCutMI().setEnabled(true);
				gui.getButtonCut().setEnabled(true);
				gui.getCopyMI().setEnabled(true);
				gui.getButtonCopy().setEnabled(true);
				gui.getPasteMI().setEnabled(true);
				gui.getButtonPaste().setEnabled(true);
				gui.getButtonTrace().setEnabled(false);
				gui.getTraceMI().setEnabled(false);
				GUI.clearStatus();
				DockingManager.display(gui.getModePage());
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class LexiconAction extends AbstractAction {
		GUI gui;
		LexiconViewer lexiconViewer;
		
		public LexiconAction(GUI gui, LexiconViewer lexiconViewer) {
			super(lexiconViewer.getName(), lexiconViewer.getIcon());
			this.gui = gui;
			this.lexiconViewer = lexiconViewer;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(DockingManager.isDocked((Component)viewLexicon)) {
					gui.getButtonLexicon().setSelected(false);
					DockingManager.close(viewLexicon);
				}else{
					gui.getButtonLexicon().setSelected(true);
					lexiconViewer = new LexiconViewer(gui);
					lexiconViewer.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
					viewLexicon.setContentPane(lexiconViewer.getViewerPanel());
					DockingManager.display(viewLexicon);
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class ChunksAction extends AbstractAction {
		GUI gui;
		ChunksViewer chunksViewer;
		
		public ChunksAction(GUI gui, ChunksViewer chunksViewer) {
			super(chunksViewer.getName(), chunksViewer.getIcon());
			this.gui = gui;
			this.chunksViewer = chunksViewer;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(DockingManager.isDocked((Component)viewChunks)) {
					gui.getButtonChunks().setSelected(false);
					DockingManager.close(viewChunks);
				}else{
					gui.getButtonChunks().setSelected(true);
					chunksViewer = new ChunksViewer(gui);
					chunksViewer.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
					viewChunks.setContentPane(chunksViewer.getViewerPanel());
					DockingManager.display(viewChunks);
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class TemplatesAction extends AbstractAction {
		GUI gui;
		TemplatesViewer templatesViewer;
		
		public TemplatesAction(GUI gui, TemplatesViewer templatesViewer) {
			super(templatesViewer.getName(), templatesViewer.getIcon());
			this.gui = gui;
			this.templatesViewer = templatesViewer;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(DockingManager.isDocked((Component)viewTemplates)) {
					gui.getButtonTemplates().setSelected(false);
					DockingManager.close(viewTemplates);
				}else{
					gui.getButtonTemplates().setSelected(true);
					templatesViewer = new TemplatesViewer(gui);
					templatesViewer.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
					viewTemplates.setContentPane(templatesViewer.getViewerPanel());
					DockingManager.display(viewTemplates);
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class UnusedAction extends AbstractAction {
		GUI gui;
		UnusedSentencesViewer unusedViewer;
		
		public UnusedAction(GUI gui, UnusedSentencesViewer unusedViewer) {
			super(unusedViewer.getName(), unusedViewer.getIcon());
			this.gui = gui;
			this.unusedViewer = unusedViewer;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(DockingManager.isDocked((Component)viewUnused)) {
					gui.getButtonUnused().setSelected(false);
					DockingManager.close(viewUnused);
				}else{
					gui.getButtonUnused().setSelected(true);
					unusedViewer = new UnusedSentencesViewer(gui);
					unusedViewer.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
					viewUnused.setContentPane(unusedViewer.getViewerPanel());
					DockingManager.display(viewUnused);
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class StatusAction extends AbstractAction {
		GUI gui;
		StatusViewer statusViewer;
		
		public StatusAction(GUI gui, StatusViewer statusViewer) {
			super(statusViewer.getName(), statusViewer.getIcon());
			this.gui = gui;
			this.statusViewer = statusViewer;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(DockingManager.isDocked((Component)viewStatus)) {
					gui.getButtonStatus().setSelected(false);
					DockingManager.close(viewStatus);
				}else{
					gui.getButtonStatus().setSelected(true);
					statusViewer = new StatusViewer();
					statusViewer.getViewerPanel().setBorder(new LineBorder(Color.GRAY, 1));
					viewStatus.setContentPane(statusViewer.getViewerPanel());
					DockingManager.display(viewStatus);
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class TrainAction extends AbstractAction {
		GUI gui;
		
		public TrainAction(GUI gui) {
			super("TrainAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
	        GUI.getProgressBar().setIndeterminate(true);
	        GUI.getTimer().start();
			if(gui.getMode() instanceof TrainingModeViewer) {
				final SwingWorker worker = new SwingWorker() {
		            public Object construct() {
						//Training
						try {
							GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
							gui.setMIandButtonsEnabled(false);
							GUI.isDone = false;
							GUI.clearStatus();
							GUI.appendToStatus("Initializing Training...");
							TrainingModeViewer trainingModeViewer = (TrainingModeViewer)gui.getMode();
							trainingModeViewer.trainAction();
							
			//				gui.clearStatus();
			//				gui.appendToStatus("Training Completed.");
			//				GUI.clearStatus();
			//				GUI.appendToStatus("Training Completed.");
					
							//Refresh chunks & templates viewers
							if(DockingManager.isDocked((Component)gui.getChunksView()))
								gui.refreshTable(gui.getChunksViewer());
							if(DockingManager.isDocked((Component)gui.getTemplatesView()))
								gui.refreshTable(gui.getTemplatesViewer());
							if(DockingManager.isDocked((Component)gui.getUnusedView()))
								gui.refreshTable(gui.getUnusedViewer());
							
							//Display Trace Option
							gui.getTraceMI().setEnabled(true);
							gui.getButtonTrace().setEnabled(true);
						} finally {
							GUI.getFrame().setCursor(Cursor.getDefaultCursor());
							gui.setMIandButtonsEnabled(true);
						}
						
						return null;
		            }

		            public void finished() {
						GUI.isDone = true;
		            }
		        };
		        worker.start();
			}
		}
	}

	class TranslateAction extends AbstractAction {
		GUI gui;
		
		public TranslateAction(GUI gui) {
			super("TranslateAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
	        GUI.getProgressBar().setIndeterminate(true);
	        GUI.getTimer().start();
			if(gui.getMode() instanceof TranslationModeViewer) {
				final SwingWorker worker = new SwingWorker() {
		            public Object construct() {
						try {
							GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
							gui.setMIandButtonsEnabled(false);
							GUI.isDone = false;
							GUI.clearStatus();
							GUI.appendToStatus("Initializing Translation...");
							TranslationModeViewer translationModeViewer = (TranslationModeViewer)gui.getMode();
							translationModeViewer.translateAction();
			
			//				gui.clearStatus();
			//				gui.appendToStatus("Translation Completed.");
			//				GUI.clearStatus();
			//				GUI.appendToStatus("Translation Completed.");
							
							//Display Trace Option
							gui.getTraceMI().setEnabled(true);
							gui.getButtonTrace().setEnabled(true);
						} finally {
							GUI.getFrame().setCursor(Cursor.getDefaultCursor());
							gui.setMIandButtonsEnabled(true);
						}
						
						return null;
					}

		            public void finished() {
						GUI.isDone = true;
		            }
		        };
		        worker.start();
			}
		}
	}

	class TraceAction extends AbstractAction {
		GUI gui;
		
		public TraceAction(GUI gui) {
			super("TraceAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(gui.getMode() instanceof TrainingModeViewer) {
					TrainingModeViewer trainingModeViewer = (TrainingModeViewer)gui.getMode();
					trainingModeViewer.traceAction();
				}else if(gui.getMode() instanceof TranslationModeViewer) {
					TranslationModeViewer translationModeViewer = (TranslationModeViewer)gui.getMode();
					translationModeViewer.traceAction();
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class ChangeLookAndFeelAction extends AbstractAction {
		GUI gui;
		String laf;
		protected ChangeLookAndFeelAction(GUI gui, String laf) {
			super("ChangeTheme");
			this.gui = gui;
			this.laf = laf;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(currentLookAndFeel != laf) {
					currentLookAndFeel = laf;
					String lafName = null;
					if(laf == mac) lafName = getString("LafMenu.mac_label");
					if(laf == metal) lafName = getString("LafMenu.java_label");
					if(laf == motif) lafName = getString("LafMenu.motif_label");
					if(laf == windows) lafName = getString("LafMenu.windows_label");
					if(laf == gtk) lafName = getString("LafMenu.gtk_label");
					updateLookAndFeel();
					for(int i = 0; i < lafMenu.getItemCount(); i++) {
						JMenuItem item = lafMenu.getItem(i);
						if(item.getText() == lafName) {
							item.setSelected(true);
						} else {
							item.setSelected(false);
						}
					}
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	 class HelpAction extends AbstractAction {
		HelpViewer helpViewer;
		
		public HelpAction(HelpViewer helpViewer) {
			super(helpViewer.getName(), helpViewer.getIcon());
			this.helpViewer = helpViewer;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(helpViewer.getViewerFrame() == null) {
					helpViewer.init();
				}else {
					helpViewer.getViewerFrame().setVisible(true);
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class AboutAction extends AbstractAction {
		GUI gui;
		
		protected AboutAction(GUI gui) {
			super("AboutAction");
			this.gui = gui;
		}
	
		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				if(aboutBox == null) {
					// JPanel panel = new JPanel(new BorderLayout());
					JPanel panel = new AboutPanel(gui);
					panel.setLayout(new BorderLayout());
			
					aboutBox = new JDialog(GUI.getFrame(), getString("AboutBox.title"), false);
							aboutBox.setResizable(false);
					aboutBox.getContentPane().add(panel, BorderLayout.CENTER);
			
					// JButton button = new JButton(getString("AboutBox.ok_button_text"));
					JPanel buttonpanel = new JPanel();
					buttonpanel.setOpaque(false);
					JButton button = (JButton) buttonpanel.add(
						new JButton(getString("AboutBox.ok_button_text"))
					);
					panel.add(buttonpanel, BorderLayout.SOUTH);
			
					ActionListener cursorDoIt = CursorController.createListener(GUI.getFrame(), new OkAction(aboutBox));
					button.addActionListener(cursorDoIt);
	//				button.addActionListener(new OkAction(aboutBox));
				}
				aboutBox.pack();
				Point p = gui.getLocationOnScreen();
				aboutBox.setLocation(p.x+104, p.y+94);
				aboutBox.setVisible(true);
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class OkAction extends AbstractAction {
		JDialog aboutBox;
	
		protected OkAction(JDialog aboutBox) {
			super("OkAction");
			this.aboutBox = aboutBox;
		}

		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				aboutBox.setVisible(false);
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	class MultiScreenAction extends AbstractAction {
		static final int ALL_SCREENS = -1;
		int screen;
		protected MultiScreenAction(GUI gui, int screen) {
			super("MultiScreenAction");
			this.screen = screen;
		}

		public void actionPerformed(ActionEvent e) {
			try {
				GUI.getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				GraphicsDevice[] gds = GraphicsEnvironment.
										 getLocalGraphicsEnvironment().
										 getScreenDevices();
				if (screen == ALL_SCREENS) {
					for (int i = 0; i < gds.length; i++) {
						GUI gui = new GUI(gds[i].getDefaultConfiguration());
					}
				}
				else {
					GUI gui = new GUI(gds[screen].getDefaultConfiguration());
				}
			} finally {
				GUI.getFrame().setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	// *******************************************************
	// **********************	Misc	*************************
	// *******************************************************

	class AboutPanel extends JPanel {
		ImageIcon aboutimage = null;
		GUI gui = null;
	
		public AboutPanel(GUI gui) {
			this.gui = gui;
			aboutimage = gui.createImageIcon("AboutBox.image", "AboutBox.accessible_description");
			setOpaque(false);
		}
	
		public void paint(Graphics g) {
			if(aboutimage != null) {
				aboutimage.paintIcon(this, g, 0, 0);
				super.paint(g);
			}else {
				g.drawRect(0,0,60,50);
				super.paint(g);
			}
		}
	
		public Dimension getPreferredSize() {
			if(aboutimage != null) {
				return new Dimension(aboutimage.getIconWidth(),
					 aboutimage.getIconHeight()+50);
			}else {
				return new Dimension(60, 100);
			}
		}
	}
}